//ok
namespace hjc {

    export class ToggleButton extends Button implements ITextural, ITextual, ITouchable {

        protected $bgSelected: string;
        protected $bgDownSelected: string;
        protected $bgDisabledSelected: string;
        protected $textSelected: string;
        protected $textDownSelected: string;
        protected $textDisabledSelected: string;
        protected $textColorSelected: number;
        protected $textColorDownSelected: number;
        protected $textColorDisabledSelected: number;
        protected $selected: boolean;
        protected $toggleModes: hjc.ToggleMode[];
        protected $unSelected: Function;
        protected $tab: hjc.Tab;

        public set bg(bg: string) { egret.superSetter(hjc.ToggleButton, this, 'bg', bg); }
        public get bg(): string { return this.$bg ? this.$bg : hjc.Skin.Default.TOGGLE_BUTTON; }
        public get bgSelected(): string { return this.$bgSelected ? this.$bgSelected : hjc.Skin.Default.TOGGLE_BUTTON_SELECTED; }
        public set bgSelected(bgSelected: string) { this.$bgSelected = bgSelected; }
        public get bgDownSelected(): string { return this.$bgDownSelected ? this.$bgDownSelected : this.bgSelected; }
        public set bgDownSelected(bgDownSelected: string) { this.$bgDownSelected = bgDownSelected; }
        public get bgDisabledSelected(): string { return this.$bgDisabledSelected ? this.$bgDisabledSelected : this.bgSelected; }
        public set bgDisabledSelected(bgDisabledSelected: string) { this.$bgDisabledSelected = bgDisabledSelected; }
        public get textSelected(): string { return this.$textSelected; }
        public set textSelected(textSelected: string) { this.$textSelected = textSelected; }
        public get textDownSelected(): string { return this.$textDownSelected ? this.$textDownSelected : this.$textSelected; }
        public set textDownSelected(textDownSelected: string) { this.$textDownSelected = textDownSelected; }
        public get textDisabledSelected(): string { return this.$textDisabledSelected ? this.$textDisabledSelected : this.$textSelected; }
        public set textDisabledSelected(textDisabledSelected: string) { this.$textDisabledSelected = textDisabledSelected; }
        public get textColorSelected(): number { return this.$textColorSelected; }
        public set textColorSelected(colorSelected: number) { this.$textColorSelected = colorSelected; }
        public get textColorDownSelected(): number { return this.$textColorDownSelected ? this.$textColorDownSelected : this.$textColorSelected; }
        public set textColorDownSelected(colorDownSelected: number) { this.$textColorDownSelected = colorDownSelected; }
        public get textColorDisabledSelected(): number { return this.$textColorDisabledSelected ? this.$textColorDisabledSelected : this.$textColorSelected; }
        public set textColorDisabledSelected(colorDisabledSelected: number) { this.$textColorDisabledSelected = colorDisabledSelected; }
        public get toggleModes(): hjc.ToggleMode[] { return this.$toggleModes; }
        public addToggleModes(...modes: hjc.ToggleMode[]): ToggleButton { this.$toggleModes.pushUnique(...modes); return this; }
        public get selected(): boolean { return this.$selected; }
        public set selected(selected: boolean) { this.$selected = selected; this.invalidateState(); }
        public get tab(): hjc.Tab { return this.$tab; }
        public set tab(tab: hjc.Tab) { this.$tab = tab; this.invalidateState(); }

        protected _init(): void {
            super._init();
            this.name = "切换按钮";
            this.$sound = 'click_wav';
            this.$toggleModes = [];
            this.$selected = false;
        }

        public setBgSelected(bgSelected: string, bgDisabledSelected?: string, bgDownSelected?: string): ToggleButton {
            this.$bgSelected = bgSelected;
            if (bgDisabledSelected) this.$bgDisabledSelected = bgDisabledSelected;
            if (bgDownSelected) this.$bgDisabledSelected = bgDownSelected;
            this.invalidateState();
            return this;
        }

        public setTextSelected(textSelected: string, params?: TText): ToggleButton {
            this.$textSelected = textSelected;
            this.invalidateState();
            if (notEmpty(params)) ui.setText(this.lbl, params);
            return this;
        }

        public setToggleBg(toggleBg: string, s9grids?: hjc.S9GridsOpitons, toggleDisabled?: string, toggleDown?: string): ToggleButton {
            this.$bg = toggleBg;
            this.$bgSelected = toggleBg + '_selected';
            if (notEmpty(s9grids)) this.setBgS9grids(s9grids);
            if (toggleDisabled) { this.$bgDisabled = toggleDisabled; this.$bgDisabledSelected = toggleDisabled + '_selected'; }
            if (toggleDown) { this.$bgDown = toggleDown; this.$bgDownSelected = toggleDown + '_selected'; }
            this.invalidateState();
            return this;
        }

        protected getCurrentState(): string {
            let state = super.getCurrentState();
            effect.toToggle(this, this.$selected, ...this.$toggleModes);
            if (this.$selected) {
                if (state === hjc.Skin.State.UP) return hjc.Skin.State.UP_SELTECTED;
                else if (state === hjc.Skin.State.DOWN) return hjc.Skin.State.DOWN_SELTECTED;
                else return hjc.Skin.State.DISABLED_SELTECTED;
            } else return state;
        }

        public setToggled(selected: Function, unSelected?: Function, context?: any): ToggleButton {
            super.setClicked(selected, context);
            if (isFunc(unSelected)) this.$unSelected = unSelected;
            return this;
        }

        protected _applyClick(inside: boolean): void {
            if (this.$tab) this.tab.select = this;
            else this.selected = !this.$selected;
            if (this.$selected && isFunc(this.$clicked)) this.$context ? Reflect.apply(this.$clicked, this.$context, [inside, true]) : this.$clicked(inside, true);
            else if (!this.$selected) {
                if (isFunc(this.$unSelected)) {
                    this.$context ? Reflect.apply(this.$unSelected, this.$context, [inside, false]) : this.$unSelected(inside, false);
                } else if (isFunc(this.$clicked)) this.$context ? Reflect.apply(this.$clicked, this.$context, [inside, false]) : this.$clicked(inside, false);
            }
        }
    }
}